/**
 * 基本图形类
*/

#ifndef __ISHAPE_H__
#define __ISHAPE_H__

#include "glm_use.h"
#include "Texture.h"
#include "m_shader.h"
#include <vector>

//带法线的顶点数据，为了方便以后可能加光照
struct _Vertex
{
    glm::vec3 pos;
    glm::vec3 normal;
    glm::vec2 texCoords;
    _Vertex(glm::vec3 p = glm::vec3(0), glm::vec3 n = glm::vec3(0), glm::vec2 t = glm::vec2(0)) : pos(p), normal(n), texCoords(t) {}
};

class IShape
{
protected:
    //颜色
    glm::vec3 color;

public:
    IShape(glm::vec3 color = glm::vec3(0.0));
    void setColor(float r, float g, float b);
    void setColor(glm::vec3 col) { setColor(col.x, col.y, col.z); }
    virtual void draw(Shader shader, float x, float y, float z) = 0;
    void draw(Shader shader, glm::vec3 pos) { draw(shader, pos.x, pos.y, pos.z); }
};

class Block : public IShape
{
    //x方向长度，y方向长度和z方向长度
    float width, height, depth;
    //纹理
    Texture texture;
    //镜面光纹理
    Texture spec_texture;
    //顶点数据和顶点缓冲
    static unsigned int VAO, VBO;
    //顶点
    static std::vector<_Vertex> vertices;

public:
    //默认构造函数
    Block() = default;
    //拷贝构造函数
    Block(const Block &);
    //构造函数
    Block(float width, float height, float depth);
    //设置纹理
    void setTexture(Texture texture);
    //设置镜面光纹理
    void setSpecTexture(Texture texture);
    //设置大小
    void setSize(float width, float height, float depth);
    //以(x, y, z)为中心绘制图形
    virtual void draw(Shader shader, float x, float y, float z);
    //获得长方体大小
    glm::vec3 getSize() const;

    //初始化静态数据
    static void init();
};

class Ball : public IShape
{
    //半径
    float radius;
    //颜色
    glm::vec3 color;
    //顶点数据和缓冲（这个球其实是个很多面的多面体哦
    static unsigned int VAO, VBO;
    //顶点坐标
    static std::vector<_Vertex> vertices;

public:
    //默认构造函数
    Ball() = default;
    //拷贝构造函数
    Ball(const Ball &);
    //构造函数
    Ball(float radius);
    //绘制图形
    virtual void draw(Shader shader, float x, float y, float z);
    //设置大小（半径
    void setSize(float radius);
    //获得大小（半径
    float getSize() const;

    //初始化静态数据
    static void init();
};

void shapeInit();
bool checkCollision(Block block, glm::vec3 posBlock, Ball ball, glm::vec3 posBall);
#endif